/*
 * Copyright (C), 2002-2014, 你的兔宝宝电子商务有限公司
 * FileName: Collections.java
 * Author:   你的兔宝宝
 * Date:     2014-6-16 下午8:43:19
 * Description: 集合工具类//模块目的、功能描述      
 * History: //修改记录
 * <author>      <time>      <version>    <desc>
 * 修改人姓名             修改时间            版本号                  描述
 */
package com.baby.demo.utils;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 集合工具类<br> 
 *
 * @author 你的兔宝宝
 */
@SuppressWarnings("rawtypes")
public class Collections {
    
    private static final Logger LOGGER = LoggerFactory.getLogger(Collections.class);
    
    public static final Map<String,Object> EMPTY_MAP = noop();
    
    public static final List<Map<String,Object>> EMPTY_LIST = noopl();
    
    private Collections() {
    }
    
    /**
     * 
     * 功能描述: 生成空map<br>
     * 〈功能详细描述〉
     *
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public static Map<String,Object> noop(){
        return new HashMap<String,Object>();
    }
    
    public static List<Map<String,Object>> noopl(){
        return new ArrayList<Map<String,Object>>();
    }
    
    /**
     * 
     * 功能描述: 判断是否为null<br>
     *
     * @param o
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public static boolean isNull(Object... os){
        boolean empty = false;
        for(Object o : os ){
            empty = empty || o == null;
        }
        return empty;
    }
    
    public static boolean isNotNull(Object... os){
        return !isNull(os);
    }
    
    /**
     * 
     * 功能描述: 判断是否为空<br>
     * 〈功能详细描述〉
     *
     * @param collection
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public static boolean isEmpty(Collection... collections){
        boolean empty = false;
        for(Collection collection : collections ){
            empty = empty || ( isNull(collection) || collection.isEmpty() );
        }
        return empty;
    }
    
    public static boolean isNotEmpty(Collection collection){
        return !isEmpty(collection);
    }
    
    /**
     * 
     * 功能描述: 判断是否为空<br>
     * 〈功能详细描述〉
     *
     * @param m
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public static boolean isEmpty(Map... maps){
        boolean empty = false;
        for(Map map : maps ){
            empty = empty || isEmpty(map);
        }
        return empty;
    }
    
    public static boolean isNotEmpty(Map... maps){
        return !isEmpty(maps);
    }
    
    public static boolean isEmpty(Map map){
        return isNull(map) || map.isEmpty();
    }
    
    public static boolean isNotEmpty(Map map){
        return !isEmpty(map);
    }
    
    @SuppressWarnings("unchecked")
    public static boolean isEmpty(Map map, String... keys){
        boolean empty = true;
        if( isNotEmpty(map) ){
            for( String key : keys ){
                empty = empty && Strings.isEmpty(get(map,key));
            }
        }
        return empty;
    }
    
    public static boolean isNotEmpty(Map map, String... keys){
        return !isEmpty(map,keys);
    }
    
    /**
     * 
     * 功能描述: 返回list中指定长度的部分，如果小于指定长度则直接返回目标list<br>
     *
     * @param ol    目标list
     * @param length 要返回的长度
     * @return
     */
    public static List show(List ol,int length){
        List sl = null;
        if(isNotEmpty(ol)){
            sl = ol;
            if(ol.size() > length){
                sl = ol.subList(0, length);  
            }
        }else{
            sl = new ArrayList();
        }
        return sl;
    }
    
    /**
     * 
     * 功能描述: 如果对象o为空，则返回对象s<br>
     * 〈功能详细描述〉
     *
     * @param o
     * @param s
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public static <T> T show(T o,T s){
        return isNull(o) ? s : o;
    }
    
    /**
     * 处理map中null-value的情况，处理成空字符串
     * 功能描述: <br>
     * 〈功能详细描述〉
     *
     * @param map
     * @return 
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public static Map<String,Object> show(Map<String,Object> map){
        if( isNull(map) ){
            return new HashMap<String,Object>();
        }
        return map;
    }
    
    /**
     * 
     * 功能描述: 检测填充空数据项<br>
     * 〈功能详细描述〉
     *
     * @param map
     * @param props
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public static void fill(Map<String,Object> map,String... props){
        if( isNotNull(map) ){
            for ( String prop : props) {
                map.put(prop, Strings.show(map.get(prop)));
            }
        }
    }
    
    
    
    /**
     * 获取bean中的某个属性
     * 功能描述: <br>
     * 〈功能详细描述〉
     *
     * @param obj
     * @param name
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    @SuppressWarnings("unchecked")
    public static Object get(Object obj, String name){
        Object value = null;
        if( obj instanceof Map){
            value = get((Map<String,Object>)obj, name);
        }else{
            try {
                PropertyDescriptor proDescriptor =new PropertyDescriptor(name,obj.getClass());
                Method methodGetUserName=proDescriptor.getReadMethod();
                value = methodGetUserName.invoke(obj);
            } catch (Exception e) {
                LOGGER.warn("get bean attr Error ",e);
            } 
        }
        return value;
    }
    
    public static <T> T getNumber( Map<String,?> m, String name, T def){
        T t = def;
        if( isNotEmpty(m) ){
            String value = Strings.get(m, name);
            t = Numbers.parse(def, value);
        }
        return t;
    }
    
    /**
     * 
     * 功能描述: 获取map中的属性<br>
     * 〈功能详细描述〉
     *
     * @param m
     * @param name
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public static Object get(Map<String,Object> m, String name){
        Object value = null;
        return get(m,name,value);
    }
    
    public static Object get(Map<String,Object> m, String name,Object dvalue){
        Object value = show(m).get(name);
        return value == null ? dvalue : value ;
    }
    
    public static boolean getBoolean(Map<String,Object> m, String name){
        boolean value = false;
        value = Strings.getBoolean(get(m,name), value);
        return value;
    }
   
    
    /**
     * 
     * 功能描述: 将list列表转化为以list元素中指定属性值为key的map<br>
     * 〈功能详细描述〉
     *
     * @param ol    目标列表
     * @param keyName   属性值名称
     * @return  
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public static Map<String,Map<String,Object>> list2map(List ol, String keyName){
        Map<String,Map<String,Object>> map = new HashMap<String,Map<String,Object>>();
        for(int i =0; i < ol.size(); i ++){
            Map<String,Object> smap = obj2map(ol.get(i));
            String key = Strings.get(smap,keyName);
            if(Strings.isNotBlank(key)){
                map.put(key, smap);
            }
        }
        return map;
    }
    
    public static Map<String,Map<String,Object>> list2map(List ol, String keyName,Map<String,String> renameProps){
        Map<String,Map<String,Object>> map = new HashMap<String,Map<String,Object>>();
        if(isNotEmpty(ol) && Strings.isNotBlank(keyName)){
            for(int i =0; i < ol.size(); i ++){
                Map<String,Object> smap = obj2map(ol.get(i));
                String key = Strings.get(smap,keyName);
                if(Strings.isNotBlank(key)){
                    rename1(smap, renameProps);
                    map.put(key, smap);
                }
            }
        }
        return map;
    }
    
    /**
     * list 转map
     * 〈一句话功能简述〉
     * 〈功能详细描述〉
     * @param l
     * @param key
     * @param value
     * @return
     * @see        [相关类/方法]（可选）
     * @since      [产品/模块版本] （可选）
     */
    public static Map<String,Object> list2map(List<Map<String,Object>> l, String key, String value){
        Map<String,Object> map = new HashMap<String,Object>();
        if(isNotEmpty(l)){
            for(int i=0;  i < l.size(); i ++){
                Map<String,Object> m = (Map<String,Object>) l.get(i);
                String name1 = Strings.show(m.get(key));
                Object name2 = m.get(value);
                map.put(name1,name2);
            }
        }
        return map;
    }
    
    /**
     * 
     * 功能描述: 将javabean转换为map<br>
     * 〈功能详细描述〉
     *
     * @param obj
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    @SuppressWarnings("unchecked")
    public static Map<String,Object> obj2map(Object obj){
        Map<String, Object> map = null;  
        if( obj instanceof Map ){
            map = (Map<String, Object>) obj;
        }else if( isNotNull(obj) ){
            map = new HashMap<String, Object>();
            try {  
                BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());  
                PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();  
                for (PropertyDescriptor property : propertyDescriptors) {  
                    String key = property.getName();  
                    // 过滤class属性  
                    if ( !"class".equals(key) ) {  
                        // 得到property对应的getter方法  
                        Method getter = property.getReadMethod();  
                        Object value = getter.invoke(obj);  
                        map.put(key, value);  
                    }  
                }  
            } catch (Exception e) {  
                LOGGER.error("obj2map Error ",e);  
            } 
        }
        return show(map);  
    }
    
    public static <T> T map2obj(Map<String,Object> map,Class<T> clazz){
        T obj = null;
        if( isNotNull(clazz) && isNotEmpty(map) ){
            try {
                obj = clazz.newInstance();
                BeanInfo beanInfo = Introspector.getBeanInfo( clazz );  
                PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();  
                for (PropertyDescriptor property : propertyDescriptors) {  
                    String key = property.getName();
                    Object val = map.get(key);
                    // 过滤class属性  
                    if ( !"class".equals(key) ) {
                        // 得到property对应的setter方法  
                        Method setter = property.getWriteMethod();  
                        setter.invoke(obj, new Object[]{val});
                    }  
                }
            } catch (Exception e) {
                LOGGER.warn("map2obj error",e);
            }
        }
        return obj;
    }
    
    /**
     * 
     * map的value转成list
     * 〈功能详细描述〉
     * @14040873
     * @param map
     * @return
     * @see        [相关类/方法]（可选）
     * @since      [产品/模块版本] （可选）
     */
    public static <T> List<T> map2vlist(Map<String,T> map){
        List<T> list = new ArrayList<T>();
        for(Entry<String, T> entry : map.entrySet()){
            list.add(entry.getValue());
        }
        return list;
    }
    
    /**
     * 
     * map的key转成list
     * 〈功能详细描述〉
     * @14040873
     * @param map
     * @return
     * @see        [相关类/方法]（可选）
     * @since      [产品/模块版本] （可选）
     */
    public static <T> List<String> map2klist(Map<String,T> map){
        List<String> list = new ArrayList<String>();
        for(Entry<String, T> entry : map.entrySet()){
            list.add(entry.getKey());
        }
        return list;
    }
    
    /**
     * 
     * 功能描述: map转list<br>
     * 〈功能详细描述〉
     *
     * @param map {a_prefix_0:'xxx',b_prefix_0:'xxx',a_prefix_1:'xxx',b_prefix_1:'xxx'}
     * @param length
     * @param props4prefix
     * @return [{a_prefix_0,b_prefix_0},{a_prefix_1,b_prefix_1}]
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public static List<Map<String,Object>> map2list(Map<String,Object> map,int length,String... props4prefix ){
        List<Map<String,Object>> list = new ArrayList<Map<String,Object>>(length);
        for(int i = 0; i < length; i ++ ){
            Map<String,Object> props = new HashMap<String,Object>();
            for(String prop4prefix: props4prefix){
                String propname = prop4prefix + i;
                props.put(propname, get(map,propname));
            }
            list.add(props);
        }
        return list;
    }
    	    

    /**
     * 重命名map中的属性，原属性还在
     * 功能描述: <br>
     * SNCollections.rename(o,new HashMap<String,String>(){
            {
                put("k1","v1");
                put("k2","v2");
                put("k3","v3");
            }
        });
     *
     * @param o     目标map
     * @param props 属性映射表
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public static Map<String,Object> rename(Map<String,Object> o, Map<String,String> props){
        for (Map.Entry<String, String> entry : props.entrySet()) {
            String key = entry.getKey();
            if(o.containsKey(key)){
                o.put(props.get(key), o.get(key));
            }
        }
        return o;
    }
    /**
     * 
     * 功能描述: 重命名key,删除原来的key<br>
     * 〈功能详细描述〉
     *
     * @param o
     * @param props
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public static Map<String,Object> rename1(Map<String,Object> o, Map<String,?> props){
        for (Map.Entry<String, ?> entry : props.entrySet()) {
            String key = entry.getKey();
            if(o.containsKey(key)){
                o.put(Strings.show(props.get(key)), o.get(key));
                o.remove(key);
            }
        }
        return o;
    }
    
    public static Map<String,Object> rename1(Map<String,Object> o, String jsonMap){
        Map<String,Object> props = Jsons.jsonObj2map(jsonMap);
        return rename1(o,props);
    }
    
    public static Map<String,Object> rename2(Map<String,Object> o, Map<String,?> props){
        for (Map.Entry<String, ?> entry : props.entrySet()) {
            String fkey = entry.getKey();
            String tkey = Strings.get(props, fkey);
            rename4path(o, fkey, tkey);
        }
        return o;
    }
    
    /**
     * 
     * 功能描述: 重命名路径名称<br>
     * 〈功能详细描述〉
     *
     * @param m
     * @param path
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    @SuppressWarnings("unchecked")
    public static Object rename4path(Map<String,Object> m, String fpath, String tpath){
        Object value = null;
        if( isNotEmpty(m) && Strings.isNotBlank(fpath,tpath) ){
            Map<String,Object> map = m;
            String[] fprops = fpath.split("/");
            String[] tprops = tpath.split("/");
            for (int i = 0; i < fprops.length -1; i++) {
                String fattr = fprops[i];
                String tattr = tprops[i];
                if( map.containsKey(fattr) ){
                    value = map.get(fattr);
                    map.put(tattr, value);
                    map.remove(fattr);
                    map = (Map<String, Object>) value;
                }
            }
            if( isNotEmpty(map) ){
                int last = fprops.length-1;
                String flast = fprops[last];
                String tlast = tprops[last];
                if( map.containsKey(flast) ){
                    value = map.get(flast);
                    map.put(tlast, value);
                    map.remove(flast);
                }
            }
        }
        return value;
    }
    
    /**
     * 
     * 功能描述: 非覆盖新复制所有属性<br>
     * 〈功能详细描述〉把f复制到t
     *
     * @param f
     * @param t
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public static Map<String,Object> copy1(Map<String,?> f, Map<String,Object> t){
        for (Map.Entry<String, ?> entry : f.entrySet()) {
            String key = entry.getKey();
            if(!t.containsKey(key)){
                t.put(key, f.get(key));
            }
        }
        return t;
    }
    
    /**
     * 
     * 功能描述: 覆盖复制<br>
     * 〈功能详细描述〉
     *
     * @param f
     * @param t
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public static <T> Map<String,T> copy(Map<String,T> f, Map<String,T> t){
        if( isNotNull(f,t) ){
            for (Map.Entry<String, T> entry : f.entrySet()) {
                String key = entry.getKey();
                t.put(key, f.get(key));
            }
        }
        return t;
    }
    
    /**
     * 
     * 功能描述: 获取指定list<map>中的某个属性list<br>
     * 〈功能详细描述〉
     *
     * @param ol 目标列表
     * @param attributeName 属性名称
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public static List<String> copy(List<Map<String,Object>> ol,String attributeName){
        List<String> sl = new ArrayList<String>();
        if( isNotNull(ol) ){
            for( Map<String,Object> obj : ol ){
                if(isNotNull(obj)){
                    sl.add(Strings.get(obj,attributeName));
                }
            }
        }
        return sl;
    }
    
    /**
     * 
     * 功能描述: 复制属性<br>
     * 〈功能详细描述〉
     *
     * @param f
     * @param t
     * @param props
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public static Map<String,Object> copy(Map<String,Object> f,Map<String,Object> t,String... props){
        if( isNotEmpty(f) ){
            for ( String prop : props) {
                if( f.containsKey( prop ) ){
                    t.put( prop , f.get( prop ));
                }
            }
        }
        return t;
    }
    
    /**
     * 复制map
     * 功能描述: <br>
     * 〈功能详细描述〉
     *
     * @param map
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public static Map<String,Object> copy(Map<String,Object> map){
        Map<String,Object> omap = noop();
        for (Entry<String, Object> entry:map.entrySet()) {
            String key = entry.getKey();
            omap.put(key, entry.getValue());
        }
        return omap;
    }
    
    public static Map<String,Object> copy(Map<String,Object> fmap,String... props){
        Map<String,Object> tmap = noop();
        return copy(fmap,tmap,props);
    }
    
    @SuppressWarnings("unchecked")
    public static Map<String,Object> copy(Object obj){
        Map<String,Object> omap;
        if( obj instanceof Map ){
            omap = copy( (Map<String,Object>)obj );
        }else{
            omap = obj2map(obj);
        }
        return omap;
    }
    
    /**
     * 从list-object中取属性
     * 功能描述: <br>
     * 〈功能详细描述〉
     *
     * @param ol
     * @param attributeName
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public static List<String> copy4obj(List<Object> ol,String attributeName){
        List<String> sl = new ArrayList<String>();
        if( isNotEmpty(ol) ){
            for(int i = 0; i < ol.size(); i ++){
                Object obj = ol.get(i);
                if(isNotNull(obj)){
                    sl.add(Strings.show(get(obj, attributeName)));
                }
            }
        }
        return sl;
    }
    
    public static Map<String,Object> copy4obj(Object obj,Map<String,Object> map){
        Map<String,Object> omap = copy(obj);
        copy(omap,map);
        return map;
    }
        
    public static Map<String,Object> copy4obj(Object obj,Map<String,Object> map,String... props){
        Map<String,Object> omap = copy(obj);
        copy(omap,map,props);
        return map;
    }
    
    /**
     * 
     * 功能描述: 复制属性<br>
     * 〈功能详细描述〉
     *
     * @param f
     * @param t
     * @param props
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public static Map<String,Object> copy(Map<String,Object> f,Map<String,Object> t, Map<String,?> props){
        for (Map.Entry<String, ?> entry : props.entrySet()) {
            String key = entry.getKey();
            if(f.containsKey(key)){
                t.put(Strings.get(props,key), f.get(key));
            }
        }
        return t;
    }
    
    public static Map<String,Object> copy4json(Map<String,Object> f, String jsonMap){
        Map<String,Object> props = Jsons.jsonObj2map(jsonMap);
        Map<String,Object> t = new HashMap<String,Object>();
        return copy(f,t,props);
    }
    
    public static Map<String,Object> copy4json(Map<String,Object> f,Map<String,Object> t, String jsonMap){
        Map<String,Object> props = Jsons.jsonObj2map(jsonMap);
        return copy(f,t,props);
    }
    
    public static Map<String,Object> quikcopy(Map<String,Object> f, String jsonList){
        Map<String,Object> t = new HashMap<String,Object>();
        return copy4list(f,t,jsonList);
    }
    /**
     * 
     * 功能描述: 复制属性<br>
     * 〈功能详细描述〉
     *  
     * @example copy(f,t,'['a',{c:'b'},{fkey:'',tkey:'',dvalue:''}]')
     * @param f
     * @param t
     * @param jsonList
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    @SuppressWarnings("unchecked")
    public static Map<String,Object> copy4list(Map<String,Object> f,Map<String,Object> t, String jsonList){
        List<Object> attrList = Jsons.json2list(jsonList);
        for(Object oattr : attrList){
            if( oattr instanceof String ){
                String key = Strings.show(oattr);
                //name:dvalue
                if( key.indexOf(":") >= 0 ){
                    String[] props = key.split(":");
                    if( props.length == 2 ){
                        //name:value
                        String name = props[0],dvalue = props[1];
                        t.put( name , get(f,name,dvalue) );
                    }else if( props.length == 3 ){
                        // name:type:value
                        String name = props[0],type = props[1],dvalue = props[2];
                        if( "long".equals(type) || "int".equals(type)|| "float".equals(type)|| "double".equals(type)|| "short".equals(type) ){
                            Object value = get(f,name,dvalue);
                            t.put( name , Numbers.parse(type, value) );
                        }else{
                            t.put( name , get(f,name,dvalue) );
                        }
                    }else{
                        t.put( key , get(f,key,"") );
                    }
                }else{
                    t.put( key , get(f,key,"") );
                }
            }else if( oattr instanceof Map ){
                Map<String,Object> mattr = (Map<String,Object>) oattr; 
                if( mattr.containsKey("fkey") ){
                    String fkey = (String) get( mattr, "fkey");
                    String tkey = (String) get( mattr, "tkey");
                    Object dvalue = get( mattr, "dvalue");
                    t.put( tkey , get(f,fkey,dvalue) );
                }else{
                    copy(f,t,mattr);
                }
            }
        }
        return t;
    }
    
    public static Map<String,Object> copy4list(Map<String,Object> f, String jsonList){
        Map<String,Object> t = new HashMap<String,Object>();
        return copy4list(f,t,jsonList);
    }
    
    public static Map<String,Object> copy4list(Object f, String jsonList){
        return copy4list(copy(f),jsonList);
    }
    
    
    
    
    public static Map<String,Object> copy4exclude(Map<String,Object> map,String jsonArr){
        Map<String,Object> omap = new HashMap<String,Object>();
        return copy4exclude(map,omap,jsonArr);
    } 
    
    @SuppressWarnings("unchecked")
    public static Map<String,Object> copy4exclude(Map<String,Object> fmap,Map<String,Object> tmap,String jsonArr){
        List<String> props = (List<String>) Jsons.json2list(jsonArr);
        Set<String> sprops = new HashSet<String>(props);
        Map<String,Object> omap = show(tmap);
        for (Entry<String, Object> entry:fmap.entrySet()) {
            String key = entry.getKey();
            if( !sprops.contains(key) ){
                omap.put(key, entry.getValue());
            }
        }
        return omap;
    }
    
    /**
     * 
     * 功能描述: 按路径获取map属性<br>
     * 〈功能详细描述〉
     *
     * @param m
     * @param path  a/b/c/d
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    @SuppressWarnings("unchecked")
    public static Object path(Map<String,Object> m, String path){
        Object value = null;
        if( isNotEmpty(m) && Strings.isNotBlank(path)){
            Map<String,Object> map = m;
            String[] attrs = path.split("/");
            for (int i = 0; i < attrs.length -1; i++) {
                String attr = attrs[i];
                value = map.get(attr);
                if( value != null && value instanceof Map){
                    map = (Map<String, Object>) value;
                }else{
                    break;
                }
            }
            if( isNotEmpty(map) ){
                value = map.get(attrs[attrs.length-1]);
            }
        }
        return value;
    }
    
    @SuppressWarnings("unchecked")
    public static Object path(Map<String,Object> m, String path,Object o){
        Object value = null;
        if( isNotEmpty(m) && Strings.isNotBlank(path)){
            Map<String,Object> map = m;
            String[] attrs = path.split("/");
            for (int i = 0; i < attrs.length -1; i++) {
                String attr = attrs[i];
                value = map.get(attr);
                if( map.containsKey(attr) && value instanceof Map){
                    map = (Map<String,Object>) value;
                }else{
                    value = new HashMap<String,Object>();
                    map.put(attr, value);
                    map = (Map<String, Object>) value;
                }
            }
            map.put(attrs[attrs.length-1],o);
        }
        return value;
    }
    
    /**
     * 
     * 功能描述: 按路径获取map属性<br>
     * 〈功能详细描述〉
     *
     * @param m
     * @param path  a/b/c/d
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    @SuppressWarnings("unchecked")
    public static List path2list(Map<String,Object> m, String path){
        List list = new ArrayList();
        if( isNotEmpty(m) && Strings.isNotBlank(path)){
            Map<String,Object> map = m;
            String[] attrs = path.split("/");
            Object value = null;
            for (int i = 0; i < attrs.length -1; i++) {
                String attr = attrs[i];
                value = map.get(attr);
                if( value != null && value instanceof Map){
                    map = (Map<String, Object>) value;
                }else{
                    break;
                }
            }
            if( isNotEmpty(map) ){
                value = map.get(attrs[attrs.length-1]);
                if( Strings.isNotBlank(value) ){
                    if( !value.getClass().equals( java.util.ArrayList.class ) ){
                        value.getClass().getClass().getName();
                        list.add(value);
                    }else{
                        list = (List)value;
                    }
                }
            }
        }
        return list;
    }
    
    /**
     * 
     * 功能描述: 释放context属性到request属性中<br>
     * 〈功能详细描述〉
     *
     * @param context
     * @param request
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public static void expose2request(Map<String,Object> context,HttpServletRequest request) {
        for (Map.Entry<String, Object> entry : context.entrySet()) {
            String modelName = entry.getKey();
            Object modelValue = entry.getValue();
            if (modelValue != null) {
                request.setAttribute(modelName, modelValue);
                if (LOGGER.isDebugEnabled()) {
                    LOGGER.warn("Added model object '" + modelName + "' of type [" + modelValue.getClass().getName()
                            + "] to request in view with name 'pageVew'");
                }
            } else {
                request.removeAttribute(modelName);
                if (LOGGER.isDebugEnabled()) {
                    LOGGER.warn("Removed model object '" + modelName + "' from request in view with name 'pageVew'");
                }
            }
        }
    }
    
    
    /**
     * 过滤指定包含指定属性的map
     * 功能描述: <br>
     * 〈功能详细描述〉
     *
     * @param olist
     * @param propname
     * @param propvalue
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public static <T> List<Map<String,T>> filter4include(List<Map<String,T>> olist,String propname,String... propvalues){
        List<Map<String,T>> list = new ArrayList<Map<String,T>>();
        for( Map<String,T> map : olist ){
            String value = Strings.get(map, propname);
            if( Strings.contiansIn( value , propvalues) ){
                list.add(map);
            }
        }
        return list;
    }
    public static <T> List<Map<String,T>> filter4exclude(List<Map<String,T>> olist,String propname,String... propvalues){
        List<Map<String,T>> list = new ArrayList<Map<String,T>>();
        for( Map<String,T> map : olist ){
            String value = Strings.get(map, propname);
            if( !Strings.contiansIn( value , propvalues) ){
                list.add(map);
            }
        }
        return list;
    }
    /**
     * 
     * 功能描述: 过滤包含指定属性的map<br>
     * 〈功能详细描述〉
     *
     * @param olist
     * @param propname
     * @param propvalue
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public static <T> Map<String,T> filterObj(List<Map<String,T>> olist,String propname,String propvalue){
        Map<String,T> omap = new HashMap<String,T>();
        for( Map<String,T> map : olist ){
            String value = Strings.get(map, propname);
            if( value.equals(propvalue) ){
                omap = map;
                break;
            }
        }
        return omap;
    }
    
    /**
     * 
     * 功能描述: 分割字符串<br>
     * 〈功能详细描述〉
     *
     * @example pcode_pscode,pcode_pscode,pcode_pscode
     * @param arr
     * @param s1    第一组分隔符
     * @param s2    第二组分隔符
     * @param attrs 映射属性
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public static List<Map<String,Object>> split(String arrs,String s1,final String s2,final List<String> attrs,final String key1,final String key2){
        final List<Map<String,Object>> list = new ArrayList<Map<String,Object>>();
        if( Strings.isNotBlank(arrs) ){
            String[] arr1 = arrs.split(s1);
            for(String elm : arr1){
                if( Strings.isNotBlank(elm) ){
                    String[] arr2 = elm.split(s2);
                    Map<String,Object> obj = new HashMap<String,Object>();
                    int j = 0;
                    for( String evalue : arr2 ){
                        String key = attrs.get(j);
                        if( Strings.isNotBlank(evalue) && Strings.isNotBlank(key) ){
                            obj.put(key, evalue);
                        }
                        j++;
                    }
                    if ( Strings.isNotBlank(key1) && Strings.isNotBlank(key2)) {
                        obj.put(key1 + "_" + key2, obj.get(key1) + "_" + obj.get(key2));
                    }
                    list.add(obj);
                }
            }
        }
        return list;
    }
    
    
    
    
    
    /**
     * 
     * 功能描述: 去重复<br>
     * 〈功能详细描述〉
     *
     * @param list
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public static List<String> deduplicate(List<String> list){
        Set<String> set = new HashSet<String>(list);
        return new ArrayList<String>(set);
    }
    
    @SuppressWarnings("unchecked")
    public static Map<String,Object> copy4except(Map<String,Object> fmap,Map<String,Object> tmap,String jsonArr){
        List<String> attrs = (List<String>) Jsons.json2list(jsonArr);
        Set<String> sattrs = new HashSet<String>(attrs);
        Map<String,Object> omap = show(tmap);
        for (Entry<String, Object> entry:fmap.entrySet()) {
            String key = entry.getKey();
            if( !sattrs.contains(key) ){
                omap.put(key, entry.getValue());
            }
        }
        return omap;
    }
    
}
